home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mac-Source 1994 July
/
Mac-Source_July_1994.iso
/
C and C++
/
Text⁄Files
/
Writeswell Jr. 1.0.2 Master
/
Writeswell Jr. Source
/
Scroll.c
< prev
next >
Wrap
Text File
|
1992-12-29
|
8KB
|
355 lines
/* Scroll.c
* Handle window scrolling in Writeswell, Jr.
* ©1992 Working Software, Inc.
* This source code is copyrighted. Permission is granted to use the Word Services
* portion of the Writeswell Jr. source code in your own programs, but you
* may not distribute the Writeswell Jr. word-processor code as a
* commercial product. If you modify the code, please do not call it
* Writeswell Jr. (or Writeswell.) This will ensure that people understand the
* program and don’t have to deal with a number of different versions with
* who-knows-what going on in the code.
*
* Writeswell Jr. and Writeswell are trademarks of Working Software, Inc.
* 18 Apr 92 Mike Crawford
*/
#include <EPPC.h>
#include <AppleEvents.h>
#include <AEObjects.h>
#include "AERegistry.h"
#include "TBConstants.h"
#include "TBGlobals.h"
#include "Scroll.h"
void DoControl( WindowPtr theWindow, ControlHandle ctlHdl, short partCode, Point where )
{
short oldVal;
short newVal;
gScrollWindow = theWindow;
switch ( partCode ){
case inUpButton:
case inDownButton:
case inPageUp:
case inPageDown:
TrackControl( ctlHdl, where, TrackScrollBar );
break;
case inThumb:
oldVal = GetCtlValue( ctlHdl );
TrackControl( ctlHdl, where, (ProcPtr)NULL );
newVal = GetCtlValue( ctlHdl );
if ( newVal != oldVal ){
ScrollText( oldVal, newVal, ctlHdl );
}
break;
}
return;
}
pascal void TrackScrollBar( ControlHandle ctlHdl, short partCode )
{
short max;
short min;
short val;
short newVal;
max = GetCtlMax( ctlHdl );
min = GetCtlMin( ctlHdl );
val = GetCtlValue( ctlHdl );
newVal = val;
switch ( partCode ){
case inUpButton:
if ( val > min )
newVal = val - 1;
break;
case inDownButton:
if ( val < max )
newVal = val + 1;
break;
case inPageUp:
newVal = val - gLinesPerPage;
if ( newVal < min )
newVal = min;
break;
case inPageDown:
newVal = val + gLinesPerPage;
if ( newVal > max )
newVal = max;
break;
}
if ( newVal != val ){
ScrollText( val, newVal, ctlHdl );
}
return;
}
void ScrollText( short oldVal, short newVal, ControlHandle ctlHdl )
{
TEHandle textH;
short dV;
SetCtlValue( ctlHdl, newVal );
textH = (TEHandle)GetWRefCon( gScrollWindow );
/* 1.0d15 Styled TextEdit requires that we use TEGetHeight to get the height
* of the actual line, since it is variable. Under STE, lineHeight is -1.
*
* Also, TEGetHeight includes the height of both lines... If we are measuring
* the height of line 2, we want to do TEGetHeight( 2, 2, textH ). We need to
* check for cases of going up and going down. If we are at the top, though,
* we want to do TEGetHeight( 0, 1, textH )
*/
if ( newVal > oldVal ){
/* We're scrolling towards the bottom of the text */
if ( oldVal != 0 ){
newVal--;
}
dV = -TEGetHeight( oldVal, newVal, textH );
}else{
/* We're scrolling towards the top of the text */
/* STUB not sure if I gotta check if we're at the bottom */
if ( oldVal != 0 ){
newVal++;
}
dV = TEGetHeight( oldVal, newVal, textH );
}
#ifdef NEVER
dV = ( oldVal - newVal ) * (*textH)->lineHeight;
#endif
TEScroll( 0, dV, textH );
return;
}
Boolean TrackContentClick( void )
{
Point where;
Rect viewRect;
TEHandle textH;
ControlHandle ctlHdl;
GrafPtr curPort;
RgnHandle oldClip;
Rect scrollRect;
Boolean needRedraw;
/* Track the mouse while it is clicked in the window, and scroll the textEdit
* field if necessary. We must always return true. We have to set the port
* so that GetMouse will have the right window's local coordinates.
*/
GetPort( &curPort );
SetPort( gScrollWindow );
GetMouse( &where );
textH = (TEHandle)GetWRefCon( gScrollWindow );
viewRect = (*textH)->viewRect;
ctlHdl = ((WindowPeek)gScrollWindow)->controlList; /* We know there's 1 control */
needRedraw = false;
/* If the mouse is above or below the window, we fake a mouse click on the scroll bar */
if ( where.v < viewRect.top ){
TrackScrollBar( ctlHdl, inUpButton );
needRedraw = true;
} else if ( where.v > viewRect.bottom ){
TrackScrollBar( ctlHdl, inDownButton );
needRedraw = true;
}
/* We need to redraw the control so that the user can see the thumb move.
* This involved setting the clip region to include scroll bar.
*/
if ( needRedraw ){
oldClip = NewRgn();
if ( oldClip ){
GetClip( oldClip );
scrollRect = (*ctlHdl)->contrlRect;
ClipRect( &scrollRect );
Draw1Control( ctlHdl );
SetClip( oldClip );
DisposeRgn( oldClip );
}
}
SetPort( curPort );
return true;
}
void SizeVertScroll()
{
MoveControl( gVertScroll, thePort->portRect.right - 15, -1 );
SizeControl( gVertScroll, 16, thePort->portRect.bottom - thePort->portRect.top - 13 );
return;
}
void SetVertScroll( WindowPtr theWindow, ControlHandle scrollHdl )
{
short totalHeight;
short viewHeight;
TEHandle hTE;
Rect viewRect;
Rect destRect;
short nLines;
short tweenHeight;
short i;
short scrollAmt;
short offSet;
/* The limits of the scroll bar range from 0 to the first line of the last
* "windowfull" of text. That is, if there are 50 lines of text, and 10 lines
* would fit in the window, then the limits are 0 through 40. If the window is
* resized so that 20 lines of text would fit, then the limits are 0 and 30. This
* way, when the thumb is all the way at the bottom, the last line of text is at
* the bottom of the window.
*/
hTE = (TEHandle)GetWRefCon( theWindow );
nLines = (*hTE)->nLines;
totalHeight = TEGetHeight( 0, nLines - 1, hTE );
viewRect = (*hTE)->viewRect;
destRect = (*hTE)->destRect;
viewHeight = viewRect.bottom - viewRect.top;
/* if the last line of text does not fall at or below the bottom of the window,
* scroll the text down so it does, but not so much that the top line of text is
* lower than the top of the window.
*/
offSet = viewRect.top - destRect.top;
if ( totalHeight >= viewHeight && ( totalHeight - offSet < viewRect.bottom ) ){
scrollAmt = -( totalHeight - offSet - viewRect.bottom );
scrollAmt -= TEGetHeight( nLines, nLines, hTE );
TEScroll( 0, scrollAmt, hTE );
viewRect = (*hTE)->viewRect;
viewHeight = viewRect.bottom - viewRect.top;
destRect = (*hTE)->destRect;
}
if ( totalHeight < viewHeight ){
/* All of the text will fit in the window. Scroll the text so the first
* line is at the top, and turn off the scroll bar.
*/
scrollAmt = viewRect.top - (*hTE)->destRect.top;
TEScroll( 0, scrollAmt, hTE );
HiliteControl( scrollHdl, 255 );
return;
}
/* The text does not all fit. Find out how many lines from the bottom would fit */
for ( i = nLines - 1; i > 0; i-- ){
tweenHeight = TEGetHeight( nLines, i, hTE );
if ( tweenHeight >= viewHeight )
break;
}
/* i is now the line number of the first line that would be in the window if
* we had scrolled all the way to the bottom
*/
SetCtlMax( scrollHdl, i - 1 );
/* Save the number of lines on a page for later use by scroll bar tracker */
gLinesPerPage = nLines - i;
for ( i = 1; i < nLines; i++ ){
tweenHeight = TEGetHeight( 1, i, hTE );
if ( tweenHeight > viewRect.top - destRect.top )
break;
}
/* i is now the line number of the first line in the window
*/
SetCtlValue( scrollHdl, i );
HiliteControl( scrollHdl, 0 );
return;
}
void ShowSelection( TEHandle hTE )
{
short i;
short scrollAmt;
short linesInRect;
short selStart;
short viewHeight;
Rect viewRect;
Rect destRect;
short nLines;
short lineHeight;
short totalHeight;
short offset;
selStart = (*hTE)->selStart;
viewRect = (*hTE)->viewRect;
destRect = (*hTE)->destRect;
offset = viewRect.top - destRect.top;
nLines = (*hTE)->nLines;
/*totalHeight = TEGetHeight( 0, nLines - 1, hTE );*/
/* scroll as needed to desired line */
i= 0;
while( i < nLines && (selStart >= ((*hTE)->lineStarts[i])))
i++;
viewHeight = viewRect.bottom - viewRect.top;
lineHeight = TEGetHeight( 1, i, hTE );
if ( lineHeight - offset > viewRect.bottom ){
scrollAmt = (lineHeight - viewRect.bottom - offset) + viewHeight / 2;
}else if ( lineHeight - offset < viewRect.top ){
scrollAmt = -( (viewRect.top - lineHeight) + viewHeight / 2 );
}else
return;
TEScroll(0,-scrollAmt,hTE);
return;
}